package general.art;

import general.exceptions.NodeNotFoundException;

import java.sql.SQLException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Cluster {

	protected Set<Node> clusterNodes = new HashSet<Node>();
	//private Map<Node, Link>clusterLinks =  new HashMap<Node, Link>();
	protected Set<Link>clusterLinks =  new HashSet<Link>();

	private final int mDepth;
	

	/**
	 * 
	 * @param seedNodeId
	 * @param depth
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws ClassNotFoundException
	 * @throws SQLException
	 * @throws NodeNotFoundException
	 */
	public Cluster(final int seedNodeId, final int depth) throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException, NodeNotFoundException{

		mDepth = depth;
		Node seedNode = Node.FIND_NODE(seedNodeId); // creates the seed node from the id
		clusterNodes.add(seedNode);
		int count = 0;

		Set<Node> rengeSet = new HashSet<Node>();
		rengeSet.add(seedNode);
		
		do{

			//System.out.println(count);
			Set<Node> newFringe = new HashSet<Node>();
			
			for(Node n : rengeSet){

				List<Link> linksFromSeed = Link.FIND_LINKS_FROM_NODE(n.getKey()); // all links from the node :s	
				
				for(Link l : linksFromSeed){

					clusterLinks.add(l);
					addNonDupNode(newFringe, l.getNode1());
					addNonDupNode(newFringe, l.getNode2());

				}

				
				
				
			}

			rengeSet = newFringe;
			//System.out.println("new Fringe Size: " + newFringe.size());
			//System.out.println("new Fringe Size: " + rengeSet.size());
			count++;
		} while (!rengeSet.isEmpty() && count < depth);

	}

	/**
	 * 
	 * Add nodes to the outerset if its not already in the cluster, this saves time by not itterating through  node which have already been put in the cluster
	 * @param outerSet
	 * @param newNode
	 */
	public void addNonDupNode(Set<Node> outerSet, Node newNode){

		
		StringBuilder myBuilder = new StringBuilder();
		
		myBuilder.append(newNode.getName());
		
		//dont put it in the outset if it is in the cluster all ready already.
		if(!clusterNodes.contains(newNode)){

			myBuilder.append(" added");
			
			outerSet.add(newNode);
			clusterNodes.add(newNode);
		}		
		
		myBuilder.append("\n");
		
		//System.out.println(myBuilder.toString());
		
	}

	public String toString(){

		StringBuilder myBuilder = new StringBuilder();

		myBuilder.append(clusterNodes.size() + "\n");
		myBuilder.append(clusterLinks.size() + "\n");

		for(Node n : clusterNodes){

			myBuilder.append(n.toString() + "\n");			

		}

		for(Link l : clusterLinks){

			myBuilder.append(l.toString() + "\n");			

		}

		return myBuilder.toString();

	}

	public Set<Node> getNodes(){


		return clusterNodes;

	}
	
	public Set<Link> getLinks(){
		
		
		return clusterLinks;
		
	}
	
	public boolean contains(Node n){
		
		return clusterNodes.contains(n);
		
	}

	public int getDepth(){
		
		return mDepth;
		
	}

	public boolean linked(Node one, Node two){
		
		return false;
		
	}
	
	
	
	public static void main(String [] args ) throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException, NodeNotFoundException{

		Cluster myCluster = new Cluster(10, 3);
		System.out.println("");
		System.out.println("cluster:");
		System.out.println(myCluster.toString());

	}


}
